Skip to content

feat: optional lazy unpack wrappers (#40) - #25691

Merged
godsflaw merged 2 commits into
msgpack:masterfrom
enochgroot:feat/lazy-unpack
Sep 19, 2026
Merged

godsflaw merged 2 commits into
msgpack:masterfrom
enochgroot:feat/lazy-unpack

Conversation

@enochgroot

Copy link
Copy Markdown
Collaborator

Summary

  • Adds unpack(buf, { lazy: true }) so MessagePack maps/arrays become accessor wrappers instead of fully converting nested values up front (issue Optinally wrap msgpack_object instead of converting to V8 object #40).
  • One-argument unpack(buf) is still eager. Nested values convert on read; toJSON / inspect.custom fully materialize so JSON.stringify and util.inspect do not hang.
  • __proto__ / constructor stay own properties, same as eager unpack. Incomplete input still returns null; oversized headers still throw.

This branch is stacked on unmerged feat/pack-type-hints (#52 / PR #25690). Merge that first, or this PR will include those commits.

Test plan

  • npm test — 208 tests, 0 failures (23 new in test/lazy.test.js)
  • npm run coverage:js — 100% statements / branches / functions / lines on lib/ + bin/
  • npm run coverage:native — 95.7% lines (1002/1047), 95.5% branches (976/1022), 100% functions (66/66); gate is 95%
  • unpack({a:1,b:2,c:[1,2,3]}) one-arg still deep-equals the source
  • unpack(buf, {lazy:true}).c[1] === 2 without reading a/b
  • JSON.stringify of lazy unpack matches eager unpack
  • __proto__ / constructor do not pollute prototypes
  • incomplete input returns null; oversized array/map headers still throw

Optional microbench on a small nested object (100k iters, this sandbox): JSON.parse 0.72 µs/op, eager unpack 2.28 µs/op, lazy wrap 4.68 µs/op, lazy then .c[1] 7.05 µs/op. Wrapper overhead dominates small payloads; the point of lazy is skipping unread nested conversion on large maps, not beating eager on tiny objects.

Closes #40

- unpack(buf, { lazy: true }) wraps maps/arrays as accessors
- keep the msgpack zone and source Buffer alive with the wrapper
- toJSON fully materializes; util.inspect does not hang
- Copy the caller Buffer before msgpack_unpack_next when lazy is set
- str/bin aliases session-owned bytes, not the transferable backing store
- Add a transfer test for str and bin after structuredClone detach
@godsflaw
godsflaw merged commit adad486 into msgpack:master Sep 19, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optinally wrap msgpack_object instead of converting to V8 object

2 participants